package com.entrogy.controller;

import com.entrogy.api.ThdidPersonApi;
import com.entrogy.bean.*;
import com.entrogy.service.*;
import com.entrogy.timing.ChangePersonTimeThread;
import com.entrogy.timing.TimingTaskService;
import com.entrogy.utils.*;
import com.entrogy.utils.constants.Constants;
import com.entrogy.utils.constants.ErrorEnum;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author xhs
 * @date 2019-4-23
 */
@RestController
@Transactional
@RequestMapping(value = "/studentcontroller")
@Api(description = "对学生及其家长信息操作的相关接口")
public class StudentController {

    private static final Logger logger = LoggerFactory.getLogger(StudentController.class);

    @Value("${show.image.url}")
    private String showImage;

    @Value("${image.storage.host}")
    private String imageHost;

    @Value("${image.storage.port}")
    private String hostPort;

    @Autowired
    private StudentService studentService;//学生信息service接口

    @Autowired
    private ParentService parentService;//家长信息service接口

    @Autowired
    private THDio thdio;

    @Autowired
    private MachineService machineService;

    @Autowired
    private SchoolService schoolService;

    @Autowired
    private UserService userService;

    @Autowired
    private ThdidPersonApi thdidPersonApi;

    @ApiOperation(value = "分页获取所有学生的信息")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "年级ID", name = "grade_id", dataType = "int", paramType = "query", required = false),
            @ApiImplicitParam(value = "班级ID", name = "class_id", dataType = "int", paramType = "query", required = false),
            @ApiImplicitParam(value = "学生姓名", name = "student_name", dataType = "String", paramType = "query", required = false),
            @ApiImplicitParam(name = "page", value = "当前页数", required = true, dataType = "Integer", paramType = "query"),
            @ApiImplicitParam(value = "每页条数", name = "total", dataType = "int", paramType = "query", required = true)
    })
    @RequestMapping(value = "/gettotalstudentList", method = RequestMethod.POST)
    public PageBean<Map<String, Object>> getTotalStudents(Integer schoolCode, Integer gradeId, Integer courseId, String studentName, Integer currentPage, Integer pageSize) {
        Map<String, Object> map = new HashMap<>();
        if (schoolCode != null && schoolCode > 0) {
            map.put("school_code", schoolCode);
        }
        if (gradeId != null && gradeId > 0) {
            map.put("grade_id", gradeId);
        }
        if (courseId != null && courseId > 0) {
            map.put("course_id", courseId);
        }
        if (studentName != null && !"".equals(studentName)) {
            map.put("student_name", studentName);
        }
        int total2 = studentService.getTotal(map);
        PageHelper.startPage(currentPage, pageSize);
        List<Map<String, Object>> list = studentService.getTotalStudentList(map);
        return new PageBean<Map<String, Object>>().pageBeans(list, total2,showImage);
    }

    @ApiOperation(value = "新增学生")
    @RequestMapping(value = "/insertstudent", method = RequestMethod.POST)
    public Map<String, Object> insertStudent(@ModelAttribute("studentEntity") StudentEntity studentEntity, int schoolCode) {
        studentEntity.setSchoolCode(schoolCode);
        Map<String, Integer> thdidInfo = new HashMap<>();
        if (StringUtils.isNoneBlank(studentEntity.getStudentBase64())){
            StudentBaseEntity student = new StudentBaseEntity();
            student.setIcNumber(studentEntity.getIcNumber()).setStudentName(studentEntity.getStudentName())
                    .setPhotoUrl(studentEntity.getStudentBase64()).setGender(studentEntity.getSex()).setIdNumber(studentEntity.getIdNumber());
            thdidInfo = thdidPersonApi.addStudentToAll(student, schoolCode);
        }
        Integer studentThdidAi06Id = thdidInfo.get("studentThdidAi06Id");
        Integer studentThdidAi16Id = thdidInfo.get("studentThdidAi16Id");
        studentEntity.setStudentThdid(studentThdidAi06Id);//设置实义德的AI06的后台id
        studentEntity.setStudentThdidAi16Id(studentThdidAi16Id);
        thdidPersonApi.pushPersonToAll(studentThdidAi06Id, studentThdidAi16Id, schoolCode, null, null, null, "添加学生");
        //设置学生走读类型默认为000
        studentEntity.setAllowTime("000");
        int code = studentService.insertStudent(studentEntity);
        if (code == 1) {
            return ApiReturnUtil.success("新增成功", "");
        }
        return ApiReturnUtil.error("新增失败");
    }

    @ApiOperation(value = "修改学生信息")
    @RequestMapping(value = "/updateStudent", method = RequestMethod.POST)
//    @RequiresPermissions("student:update")
    public Map<String, Object> updateStudent(String studentName, Integer id, Integer busLineId, Integer schoolCode, String studentBase64) {
        StudentEntity studentEntity = new StudentEntity();
        studentEntity.setStudentName(studentName == null ? null : studentName);
        studentEntity.setSchoolbuslineId(busLineId == null ? "-1" : String.valueOf(busLineId));
        studentEntity.setStudentBase64(studentBase64 == null ? null : studentBase64);
        studentEntity.setId(id);
        // 更新实义德后台的信息
        if (StringUtils.isNoneBlank(studentBase64) || StringUtils.isNoneBlank(studentName)) {
            StudentBaseEntity student = new StudentBaseEntity();
            student.setStudentName(studentName)
                    .setPhotoUrl(studentBase64)
                    .setStudentId(id);
            Map<String, Integer> thdidInfo = thdidPersonApi.updateStudentToAll(student, schoolCode);
            // 修改可能会新增，所以直接更新学生的实义德后台id
            studentService.updateStudentAllThdid(id, thdidInfo);
        }
        int code = studentService.updateStudent(studentEntity);
        if (code == 1) {
            return ApiReturnUtil.success("修改成功", "");
        }
        return ApiReturnUtil.error("修改失败");
    }

    @ApiOperation(value = "新增/修改学生家长信息")
    @RequestMapping(value = "/insertParent", method = RequestMethod.POST)
    public Map<String, Object> insertParent(String parent_visitor_name, String parent_visitor_phone,
                                            String schoolCode, Integer id, String parent_id,
                                            int parent_visitor_Type, String parentBase64) {
        ParentVisitorEntity parentVisitorEntity = new ParentVisitorEntity();
        parentVisitorEntity.setParentVisitorName(parent_visitor_name);
        parentVisitorEntity.setParentVisitorBase64(parentBase64);
        parentVisitorEntity.setParentVisitorPhone(parent_visitor_phone);
        parentVisitorEntity.setParentVisitorSchoolCode(Integer.parseInt(schoolCode));
        parentVisitorEntity.setParentId(parent_id);
        parentVisitorEntity.setParentVisitorId(parent_id);
        parentVisitorEntity.setParentVisitorType(parent_visitor_Type);
        int code;
        if (StringUtils.isNoneBlank(parent_id)) { // 编辑家长信息
            // 是否修改电话号码
            boolean isEditPhone = !parentService.getparentById(parent_id).getParentVisitorPhone().equals(parent_visitor_phone);
            // 更新家长信息时也可能更新的新号码已经存在我们的系统当中，存在的话更新学生和家长的对应关系，不存在的话更新家长信息
            if (isEditPhone){
                boolean hasMultipleChild = false;
                // 判断该生正在新增家长电话是否和另一个家长重复
                List<ParentVisitorEntity> parentList = parentService.listParentByStudentId(id);
                for (ParentVisitorEntity visitorEntity : parentList) {
                    if (!visitorEntity.getParentVisitorId().equals(parent_id)){
                        if (visitorEntity.getParentVisitorPhone().equals(parent_visitor_phone))
                            return ApiReturnUtil.error("修改失败，该生两个家长电话号码不能相同！");
                    }
                }
                List<StudentBasicInfoEntity> studentList = parentService.listStudentByParentId(parent_id);
                if (studentList.size() > 1){
                    hasMultipleChild = true;
                }
                // 如果该家长有多个孩子，那么需要新增修改后的家长电话号码为一个新的账号而不是修改
                if (!hasMultipleChild){
                    ParentVisitorEntity temp = parentService.getParentByPhone(parent_visitor_phone);
                    if (temp != null){
                        Map<String, Object> map = new HashMap<>();
                        map.put("id", id);
                        map.put("parent_id", temp.getParentVisitorId());
                        if (parent_visitor_Type == 1) {
                            map.put("type", 1);
                        } else {
                            map.put("type", 2);
                        }
                        code = studentService.updateStuent1(map);
                    }else {
                        code = parentService.updateParent(parentVisitorEntity);
                    }
                }else {
                    return addParent(id, parentVisitorEntity);
                }
            } else {
                code = parentService.updateParent(parentVisitorEntity);
            }
        } else { // 新增家长信息
            // 判断该生正在新增家长电话是否和另一个家长重复
            List<ParentVisitorEntity> parentList = parentService.listParentByStudentId(id);
            if(parentList.size() == 1){
                if (parentList.get(0).getParentVisitorPhone().equals(parentVisitorEntity.getParentVisitorPhone())){
                    return ApiReturnUtil.error("新增失败，该生两个家长电话号码不能相同！");
                }
            }
            return addParent(id, parentVisitorEntity);
        }

        if (code == 1) {
            return ApiReturnUtil.success("更新成功", "");
        }
        return ApiReturnUtil.error("更新失败");
    }

    @ApiOperation(value = "获取家长信息")
    @RequestMapping(value = "/selectParentVisitorEntityById", method = RequestMethod.POST)
    public List<Map<String, Object>> selectParentVisitorEntityById(@RequestParam(value = "student_id") int student_id, int parent_visitor_Type) {
        Map<String, Object> map = new HashMap<>();
        map.put("studentId", student_id);
        map.put("parentVisitorType", parent_visitor_Type);
        map.put("baseImage",showImage);
        List<Map<String, Object>> list = parentService.selectParentVisitorEntityById(map);
        list.add(map);
        return list;
    }


     @ApiOperation(value = "根据父母ID查询出其所有的孩子不管在那个学校的都查询出来，方便其操作")
     @ApiImplicitParam(name = "uid",value = "用户ID",dataType = "String",paramType = "query",required = true)
     @RequestMapping(value = "getstudents",method = RequestMethod.GET)
     public Map<String,Object> getStudentsByParentId(String uid){
         List<StudentEntity> lists = parentService.getStudentByParentId(uid);
         return ApiReturnUtil.success("查询成功",lists);
     }

    @ApiOperation(value = "查询学生列表带宿舍信息")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "年级ID", name = "gradeId", dataType = "int", paramType = "query", required = false),
            @ApiImplicitParam(value = "班级ID", name = "classId", dataType = "int", paramType = "query", required = false),
    })
    @GetMapping(value = "listFloorStudent")
    public Msg getStudentsByParentId(Integer gradeId, Integer classId){
        Integer schoolCode = (Integer) SecurityUtils.getSubject().getSession().getAttribute("schoolCode");
        List<com.alibaba.fastjson.JSONObject> studentList = studentService.listFloorStudent(gradeId, classId, schoolCode);
        return Msg.success().add("studentList", studentList).add("showImage", showImage);
    }

    @ApiOperation(value = "分页获取所有学生的信息--管理员视图")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "选择的学校ID", name = "selectSchoolCode", dataType = "Integer", paramType = "query"),
            @ApiImplicitParam(value = "年级ID", name = "gradeId", dataType = "Integer", paramType = "query"),
            @ApiImplicitParam(value = "班级ID", name = "classId", dataType = "Integer", paramType = "query"),
            @ApiImplicitParam(value = "学生姓名", name = "studentName", dataType = "String", paramType = "query"),
            @ApiImplicitParam(value = "通行时段", name = "allowTime", dataType = "String", paramType = "query"),
            @ApiImplicitParam(value = "当前页数",name = "currentPage",  required = true, dataType = "Integer", paramType = "query"),
            @ApiImplicitParam(value = "每页条数", name = "pageSize", required = true, dataType = "Integer", paramType = "query"),
            @ApiImplicitParam(value = "是否需要查询通行权限，1需要，0不需要", name = "requireGetPassPermission", dataType = "Integer", paramType = "query"),
    })
    @GetMapping(value = "/listSchoolStudent")
    public Msg listSchoolStudent(Integer selectSchoolCode, Integer gradeId, Integer classId, String studentName, Integer currentPage, Integer pageSize, String allowTime, Integer requireGetPassPermission) {
         PageHelper.startPage(currentPage, pageSize);
         List<StudentEntity> studentList = studentService.listSchoolAllStudent(selectSchoolCode, gradeId, classId, null, studentName, null, allowTime);
         PageInfo<StudentEntity> pageInfo = new PageInfo(studentList);
         // 适配小程序和PC端
        if (requireGetPassPermission == null || requireGetPassPermission == 1){
            SchoolThdidUrlEntity schoolThididUrlEntity = schoolService.getSchoolThdidUrlAndGroupInfo(selectSchoolCode, Constants.THDID_AI06);
            // 查询这些学生的通行权限
            try {
                for (StudentEntity studentEntity : studentList) {
                    if (!StringUtils.isNoneBlank(studentName)){
                        schoolThididUrlEntity = schoolService.getSchoolThdidUrlAndGroupInfo(studentEntity.getSchoolCode(), Constants.THDID_AI06);
                    }
                    Integer thdid = studentEntity.getStudentThdid();
                    if (thdid != 0 && thdid != null){
                        JSONArray deviceList = getDeviceList(schoolThididUrlEntity, thdid);
                        studentEntity.setDeviceList(deviceList);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                return Msg.success().add("studentList", studentList).add("totalCount", pageInfo.getTotal()).add("baseImage", showImage);
            }
        }
         return Msg.success().add("studentList", studentList).add("totalCount", pageInfo.getTotal()).add("baseImage", showImage);
    }

    @ApiOperation(value = "校验通行权限有问题的学生")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "选择的学校ID", name = "selectSchoolCode", dataType = "Integer", paramType = "query", required = false),
            @ApiImplicitParam(value = "年级ID", name = "gradeId", dataType = "Integer", paramType = "query", required = false),
            @ApiImplicitParam(value = "班级ID", name = "classId", dataType = "Integer", paramType = "query", required = false),
            @ApiImplicitParam(value = "学生姓名", name = "studentName", dataType = "String", paramType = "query", required = false),
            @ApiImplicitParam(value = "通行时间段", name = "allowTime", dataType = "String", paramType = "query", required = false),
    })
    @GetMapping(value = "/verifyPassAuthorization")
    public Msg verifyPassAuthorization(Integer selectSchoolCode, Integer gradeId, Integer classId, String studentName, String allowTime) {
         List<StudentEntity> studentList = studentService.listSchoolAllStudent(selectSchoolCode, gradeId, classId, null, studentName, null, allowTime);
         List<StudentEntity> failStudentList = new ArrayList<>();
         SchoolThdidUrlEntity schoolThididUrlEntity = schoolService.getSchoolThdidUrlAndGroupInfo(selectSchoolCode, Constants.THDID_AI06);

         // 生成当前的动态时间段表名
         String today = new SimpleDateFormat("yyyyMMdd").format(new Date());
         String cycleTableName = "dyn_cycle" + today;
        // 查询出该校所有的出门设备
        MachineEntity machine = new MachineEntity();
        machine.setSchoolCode(selectSchoolCode);
        machine.setDeviceModel(Constants.THDID_AI06).setIsout(1);
        List<String> machineIdList = machineService.listMachineId(machine);
         // 查询这些学生的通行权限
        for (StudentEntity studentEntity : studentList) {
            Integer thdid = studentEntity.getStudentThdid();
            if (thdid != 0 && thdid != null){
                // 非走读生不校验
                if ("000".equals(studentEntity.getAllowTime())){
                    continue;
                }
                JSONArray deviceList = getDeviceList(schoolThididUrlEntity, thdid);
                // 只要实义德的出门设备
                Iterator iterator = deviceList.iterator();
                while (iterator.hasNext()){
                    Object device = iterator.next();
                    String deviceName = ((JSONObject) device).getString("device_name");
                    if (!deviceName.endsWith("dm2")){
                        iterator.remove();
                    }
                }
                // 如果可通行设备的数量不一样的话，通行权限肯定有问题
                if (machineIdList.size() != deviceList.size()){
                    failStudentList.add(studentEntity);
                    continue;
                }
                // 查询学生的通行权限id
                Integer cycleId = studentService.getStudentCycleId(studentEntity.getId(), cycleTableName);
                a:for (Object device : deviceList) {
                    Integer cycleIdFromThdid = ((JSONObject) device).getInt("cycle_id");
                    Integer deviceIdFromThdid = ((JSONObject) device).getInt("device_id");
                    for (String deviceId : machineIdList) {
                        // 当设备id相等时查看通行时段是否是正确的
                        if ((Integer.valueOf(deviceId)).equals(deviceIdFromThdid)){
                            if (!cycleId.equals(cycleIdFromThdid)){
                                studentEntity.setDeviceList(deviceList);
                                failStudentList.add(studentEntity);
                                break a;
                            }
                        }
                    }
                }
            }
        }
         return Msg.success().add("failStudentList", failStudentList);
    }

    @ApiOperation(value = "查询学生信息用于IC卡管理页面")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "年级ID", name = "gradeId", dataType = "Integer", paramType = "query"),
            @ApiImplicitParam(value = "班级ID", name = "classId", dataType = "Integer", paramType = "query"),
            @ApiImplicitParam(value = "学生姓名", name = "studentName", dataType = "String", paramType = "query"),
            @ApiImplicitParam(value = "当前页数", name = "currentPage",  dataType = "Integer", paramType = "query"),
            @ApiImplicitParam(value = "每页条数", name = "pageSize", dataType = "Integer", paramType = "query"),
            @ApiImplicitParam(value = "是否需要翻页，0不需要，1需要", name = "isRequireLimit", dataType = "Integer", paramType = "query"),
            @ApiImplicitParam(value = "是否查询已绑卡学生，0未绑卡，1已绑卡，不传查全部", name = "isBind", dataType = "Integer", paramType = "query"),
    })
    @GetMapping(value = "/listStudentForIcManager")
    public Msg listStudentForIcManager(Integer gradeId, Integer classId, String studentName, Integer currentPage, Integer pageSize, Integer isRequireLimit, Integer isBind) {
        Integer schoolCode = (Integer)SecurityUtils.getSubject().getSession().getAttribute("schoolCode");
        if (schoolCode == null){
            return Msg.fail(ErrorEnum.E_20011, ErrorEnum.E_20011.getErrorMsg());
        }
        List<StudentIcEntity> studentList;
        if (isRequireLimit == 1){
            int totalCount = studentService.countStudentForIcManager(schoolCode, isBind, gradeId, classId, studentName);
            PageHelper.startPage(currentPage, pageSize);
            studentList = studentService.listStudentForIcManager(schoolCode, isBind, gradeId, classId, studentName);
            return Msg.success().add("studentList", studentList).add("showImage", showImage).add("totalCount", totalCount);
        }else {
            studentList = studentService.listStudentForIcManager(schoolCode, isBind, gradeId, classId, studentName);
            return Msg.success().add("studentList", studentList).add("showImage", showImage);
        }
    }

    @ApiOperation(value = "查询学生信息校车考勤")
    @ApiImplicitParams({
        @ApiImplicitParam(value = "校车路线", name = "busLineId", dataType = "Integer", paramType = "query"),
        @ApiImplicitParam(value = "学生姓名", name = "studentName", dataType = "String", paramType = "query"),
        @ApiImplicitParam(value = "当前页", name = "currentPage", dataType = "Integer", paramType = "query"),
        @ApiImplicitParam(value = "每页条数", name = "pageSize", dataType = "Integer", paramType = "query"),
        @ApiImplicitParam(value = "用户id", name = "uid", dataType = "String", paramType = "query"),
    })
    @GetMapping(value = "/list-student-for-bus")
    public Msg listStudentForBus(Integer busLineId, String studentName, Integer currentPage, Integer pageSize, String uid) {
        Integer schoolCode = (Integer) SecurityUtils.getSubject().getSession().getAttribute("schoolCode");
        if (schoolCode == null && StringUtils.isNoneBlank(uid)){
            schoolCode = userService.getSchoolCodeByUserId(uid);
        }
        Integer totalCount = studentService.countStudentForBus(busLineId, studentName, schoolCode);
        PageHelper.startPage(currentPage, pageSize);
        List<StudentBasicInfoEntity> studentList = studentService.listStudentForBus(busLineId, studentName, schoolCode);
        return Msg.success().add("studentList", studentList).add("totalCount", totalCount).add("showImage", showImage);
    }

    private JSONArray getDeviceList(SchoolThdidUrlEntity schoolThididUrlEntity, Integer thdid) {
        JSONObject params = new JSONObject();
        params.put("personnel_id", thdid);
        params.put("page", 1);
        params.put("amount", 500);
        JSONObject res = thdio.THD_interface(schoolThididUrlEntity.getPathUrl(), "/competence/device_list", params, true, schoolThididUrlEntity.getAccessToken());
        // 学生已授权设备列表
        JSONArray personAuthorizationDeviceList = res.getJSONObject("data").getJSONArray("device_list");
        JSONObject params1 = new JSONObject();
        params1.put("page", 1);
        params1.put("amount", 5000);
        JSONObject res1 = thdio.THD_interface(schoolThididUrlEntity.getPathUrl(), "/competence/cycle_list", params1, true, schoolThididUrlEntity.getAccessToken());
        JSONArray cycleInfoList = res1.getJSONObject("data").getJSONArray("cycle_list");
        for (Object personAuthorizationDevice : personAuthorizationDeviceList) {
            JSONObject device = (JSONObject)personAuthorizationDevice;
            Integer cycleId = device.getInt("cycle_id");
            // 得到时间段规则详细信息
            for (Object cycleInfoObject : cycleInfoList) {
                Integer cycleInfoId = ((JSONObject)cycleInfoObject).getInt("cycle_id");
                if (cycleId.equals(cycleInfoId)){
                    String cycleStr = ((JSONObject)cycleInfoObject).getString("cycle_value");
                    device.put("cycleInfo", cycleStr);
                }
            }
        }
        return personAuthorizationDeviceList;
    }

    private Map<String, Object> addParent(Integer studentId, ParentVisitorEntity parentVisitorEntity){
        int code;
        // 新增时需要判断是否该号码已存在
        ParentVisitorEntity temp = parentService.getParentByPhone(parentVisitorEntity.getParentVisitorPhone());
        String parent_visitor_id = "";
        if (temp == null){
            parent_visitor_id = ("3" + System.currentTimeMillis());
            parentVisitorEntity.setParentVisitorId(parent_visitor_id);
            code = parentService.insertParent(parentVisitorEntity);
        }
        Map<String, Object> map = new HashMap<>();
        map.put("id", studentId);
        map.put("parent_id", temp == null ? parent_visitor_id : temp.getParentVisitorId());
        if (parentVisitorEntity.getParentVisitorType() == 1) {
            map.put("type", 1);
        } else {
            map.put("type", 2);
        }
        code = studentService.updateStuent1(map);
        if (code == 1) {
            return ApiReturnUtil.success("更新成功", "");
        }
        return ApiReturnUtil.error("更新失败");
    }
}
